using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Server;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NMock;
using NMock.Constraints;

using Microsoft.Services.TfsAlert.AppCode;
using Microsoft.Services.TfsAlert.Core;
using Microsoft.Services.TfsAlert.Core.Model;

namespace Microsoft.Services.TfsAlert.Core.BusinessFacades.RegistrationBF.Impl
{
    [TestClass]
    internal partial class RegistrationManagerImpl
    {

        [TestMethod]
        public void AssertDeliveryPreferenceIsCreatedProperly()
        {
            IMock mockApplicationHelpers = new DynamicMock( typeof( ApplicationHelpers ) );

            ApplicationHelpers applicationHelpers = new ApplicationHelpers();

            Uri endpoint = applicationHelpers.BuildFullAddress();

            mockApplicationHelpers.ExpectAndReturn(
                "BuildFullAddress",
                endpoint,
                null );

            this._applicationHelpers = (ApplicationHelpers)mockApplicationHelpers.MockInstance;

            DeliveryPreference deliveryPreference = this.getDeliveryPreference();

            Assert.AreEqual<string>( endpoint.ToString(), deliveryPreference.Address,
                                     "DeliveryPreference.Address was incorrect" );
            Assert.AreEqual( DeliverySchedule.Immediate, deliveryPreference.Schedule,
                             "DeliverySchedule.Immediate wasn't set" );
            Assert.AreEqual( DeliveryType.Soap, deliveryPreference.Type, "DeliveryPreference.Type wasn't set to SOAP" );
        }

        [TestMethod]
        public void AssertGetEventServiceCallsTeamFoundationFactoryToGetAnEventService()
        {
            DynamicMock mockTeamFoundationFactory = new DynamicMock( typeof( TeamFoundationFactory ) );

            const string serverName = "FooBar-Server";

            mockTeamFoundationFactory.Expect( "GetEventService", serverName );
            mockTeamFoundationFactory.Strict = true;
            mockTeamFoundationFactory.Ignore( "Finalize" );

            this.teamFoundationFactory = (TeamFoundationFactory)mockTeamFoundationFactory.MockInstance;


            List<TfsServer> _servers = new List<TfsServer>();
            TfsServer _server = new TfsServer();
            _server.Name = serverName;
            _servers.Add(_server);

            this.TeamFoundationServers = _servers;
            //TfsEventCollection tfsEventCollection = new TfsEventCollection();
           // tfsEventCollection.TeamFoundationServer = serverName;
            //this.tfsEventCollection = tfsEventCollection;

            IEventService eventService = this.tfsEventService;

            mockTeamFoundationFactory.Verify();
        }

        [TestMethod]
        public void AssertTfsEventServicePropertyReturnsCorrectObjectWhenExplicitySet()
        {
            DynamicMock mockEventService = new DynamicMock( typeof( IEventService ) );
            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            Assert.AreSame( mockEventService.MockInstance, this.tfsEventService );
        }

        [TestMethod]
        public void AssertTeamFoundationFactoryPropertyReturnsCorrectObjectWhenExplicitySet()
        {
            TeamFoundationFactory mockTeamFoundationFactory = new TeamFoundationFactory();
            this.teamFoundationFactory = mockTeamFoundationFactory;

            Assert.AreSame( mockTeamFoundationFactory, this.teamFoundationFactory );
        }

        [TestMethod]
        public void AssertTeamFoundationServersPropertyReturnsCorrectObjectWhenExplicitySet()
        {

            List<TfsServer> _mockservers = new List<TfsServer>();
            this.TeamFoundationServers = _mockservers;

            Assert.AreSame(_mockservers, this.TeamFoundationServers);
        }

        #region (Un)Suscribe Methods Unit Tests

        /// <summary>
        /// This test does to much..  
        /// 
        /// Test for
        ///     Correct number of calls based on selected being set to true.
        ///     Correct Call to Event Service
        ///     Correct Paramerters being sent to Event Service
        ///     Correct Suscribtion ID being added to the TfsEvent
        /// </summary>
        [TestMethod]
        public void AssertAgainstSuscribeMethod()
        {
            List<TfsServer> _servers = new List<TfsServer>();
            TfsServer _server = new TfsServer();
            _server.UserName = "FooBarUserId";

            List<TfsEvent> _events = new List<TfsEvent>();

            TfsEvent tfsEvent1 = new TfsEvent();
            tfsEvent1.EventType = "TESTEventType";
            tfsEvent1.IsSelected = true;

            TfsEvent tfsEvent2 = new TfsEvent();
            tfsEvent2.EventType = "TESTEventType2";
            tfsEvent2.IsSelected = false;

            _events.Add(tfsEvent1);
            _events.Add(tfsEvent2);

            _server.Events = _events;

            _servers.Add(_server);

            this.TeamFoundationServers = _servers;

           /* TfsEventCollection tfsEventCollection = new TfsEventCollection();
            tfsEventCollection.Add( tfsEvent1 );
            tfsEventCollection.Add( tfsEvent2 );
            tfsEventCollection.TeamFoundationUserId = "FooBarUserId";

            this.tfsEventCollection = tfsEventCollection;
            */

            DynamicMock mockEventService = new DynamicMock( typeof( IEventService ) );
            mockEventService.Strict = true;
            mockEventService.Ignore( "Finalize" );

            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            int subscriptionId = 1234;

            mockEventService.ExpectAndReturn(
                "SubscribeEvent",
                subscriptionId,
                new object[]
                    {
                        _server.UserName, tfsEvent1.EventType, tfsEvent1.FilterExpression,
                        new IsAnything()
                    } );

            this.Suscribe();

            Assert.AreEqual<int>( subscriptionId, tfsEvent1.SubscriptionID );
            mockEventService.Verify();
        }

        [TestMethod]
        public void AssertAgainstUnSuscribeMethodWhenTrueAndASubscriptionId()
        {
            int subscriptionId = 1234;
            List<TfsServer> _servers = new List<TfsServer>();
            TfsServer _server = new TfsServer();
            _server.UserName = "FooBarUserId";

            List<TfsEvent> _events = new List<TfsEvent>();

            TfsEvent tfsEvent1 = new TfsEvent();
            tfsEvent1.EventType = "TESTEventType";
            tfsEvent1.IsSelected = true;
            tfsEvent1.SubscriptionID = subscriptionId;

            _events.Add(tfsEvent1);
            _server.Events = _events;

            _servers.Add(_server);

          //  TfsEventCollection tfsEventCollection = new TfsEventCollection();
          //  tfsEventCollection.Add( tfsEvent1 );
          //  tfsEventCollection.TeamFoundationUserId = "FooBarUserId";

            this.TeamFoundationServers = _servers;
           // this.tfsEventCollection = tfsEventCollection;

            DynamicMock mockEventService = new DynamicMock( typeof( IEventService ) );
            mockEventService.Strict = true;
            mockEventService.Ignore( "Finalize" );

            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            mockEventService.Expect(
                "UnsubscribeEvent",
                new object[] {subscriptionId} );

            this.UnSuscribe();

            Assert.AreEqual<int>( 0, tfsEvent1.SubscriptionID );
            mockEventService.Verify();
        }

        //todo Need to think through the unsuscribe conditions some more

        /*
         * Ignore doesn't seem to work
         
        [Ignore, TestMethod]
        public void AssertAgainstUnSuscribeMethodWhenFalseAndASubscriptionId()
        {
            int subscriptionId = 1234;

            TfsEvent tfsEvent1 = new TfsEvent();
            tfsEvent1.EventType = "TESTEventType";
            tfsEvent1.Selected = false;
            tfsEvent1.SubscriptionId = subscriptionId;

            TfsEventCollection tfsEventCollection = new TfsEventCollection();
            tfsEventCollection.Add(tfsEvent1);
            tfsEventCollection.TeamFoundationUserId = "FooBarUserId";

            this.tfsEventCollection = tfsEventCollection;

            DynamicMock mockEventService = new DynamicMock(typeof(IEventService));
            mockEventService.Strict = true;
            mockEventService.Ignore("Finalize");

            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            mockEventService.Expect(
                "UnsubscribeEvent",
                new object[] { subscriptionId });

            this.UnSuscribe();

            Assert.AreEqual<int>(0, tfsEvent1.SubscriptionId);
            mockEventService.Verify();
        }
         * 
         */

        [TestMethod]
        public void AssertAgainstUnSuscribeMethodWhenFalseAndASubscriptionIdEquals0()
        {
            List<TfsServer> _servers = new List<TfsServer>();
            int subscriptionId = 0;

            TfsServer _server = new TfsServer();
            _server.Name = "FOOBAR";
            _server.UserName = "FooBarUserId";

            TfsEvent tfsEvent1 = new TfsEvent();
            tfsEvent1.EventType = "TESTEventType";
            tfsEvent1.IsSelected = false;
            tfsEvent1.SubscriptionID = subscriptionId;

            List<TfsEvent> _events = new List<TfsEvent>();
            _events.Add(tfsEvent1);
            _server.Events = _events;
            
           _servers.Add(_server);

            this.TeamFoundationServers = _servers;
          


          //  TfsEventCollection tfsEventCollection = new TfsEventCollection();
          //  tfsEventCollection.Add( tfsEvent1 );
          //  tfsEventCollection.TeamFoundationUserId = "FooBarUserId";

          //  this.tfsEventCollection = tfsEventCollection;

            DynamicMock mockEventService = new DynamicMock( typeof( IEventService ) );
            mockEventService.Strict = true;
            mockEventService.Ignore( "Finalize" );

            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            mockEventService.ExpectNoCall(
                "UnsubscribeEvent",
                typeof( int ) );

            this.UnSuscribe();

            Assert.AreEqual<int>( 0, tfsEvent1.SubscriptionID );
            mockEventService.Verify();
        }

        [TestMethod]
        public void AssertAgainstUnSuscribeMethodWhenTrueAndASubscriptionIdEquals0()
        {
            List<TfsServer> _servers = new List<TfsServer>();
            TfsServer _server = new TfsServer();
            _server.UserName = "FooBarUserId";
            List<TfsEvent> _events = new List<TfsEvent>();


            int subscriptionId = 0;

            TfsEvent tfsEvent1 = new TfsEvent();
            tfsEvent1.EventType = "TESTEventType";
            tfsEvent1.IsSelected = true;
            tfsEvent1.SubscriptionID = subscriptionId;
            _events.Add(tfsEvent1);

            _server.Events = _events;

            _servers.Add(_server);

           // TfsEventCollection tfsEventCollection = new TfsEventCollection();
           // tfsEventCollection.Add( tfsEvent1 );
          //  tfsEventCollection.TeamFoundationUserId = "FooBarUserId";

            this.TeamFoundationServers = _servers;
           // this.tfsEventCollection = tfsEventCollection;

            DynamicMock mockEventService = new DynamicMock( typeof( IEventService ) );
            mockEventService.Strict = true;
            mockEventService.Ignore( "Finalize" );

            this.tfsEventService = (IEventService)mockEventService.MockInstance;

            mockEventService.ExpectNoCall(
                "UnsubscribeEvent",
                typeof( int ) );

            this.UnSuscribe();

            Assert.AreEqual<int>( 0, tfsEvent1.SubscriptionID );
            mockEventService.Verify();
        }

        #endregion //Suscribe Methods Unit Tests
    }
}